package com.pic.gateway.config;

import com.pic.common.utils.UserContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import com.pic.common.constants.RedisConstants;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.pic.common.constants.RedisConstants.jwt.*;

import com.pic.common.utils.UserContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import com.pic.common.constants.RedisConstants;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.pic.common.constants.RedisConstants.jwt.*;

@Order(1)
@Configuration
@Slf4j
public class GlobalFilterConfig implements GlobalFilter {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private PathFilterUtil pathFilterUtil;
//    @Autowired
//    private
//
//    jwtTokenService
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        String path=exchange.getRequest().getURI().getPath();
        log.info("全局处理器的path:{}",path);
        // 判断是否需要放行
        if (pathFilterUtil.shouldBypassFilter(path)) {
            // 对于需要放行的路径，直接放行
            return chain.filter(exchange);
        }

        //测试全部放行


        //1.获取请求的request信息
        String token = exchange.getRequest().getHeaders().getFirst(GET_TOKEN);
        log.info("token:{}",token);
        if (token == null || token.isEmpty()) {
//            return chain.filter(exchange);
            return unAuthorize(exchange);

        }

    Long ttl=stringRedisTemplate.getExpire(LOGIN_TOKEN_KEY + token, TimeUnit.SECONDS);
        log.info("ttl的时间：{}",ttl);
//        if(ttl!=null&&ttl<=0){
//            return unAuthorize(exchange);
//        }

        log.info(LOGIN_TOKEN_KEY+ ":"+token);
        //获取token的过期时间
        // 获取Token的过期时间
//        Date expirationDate = jwtTokenService.parseToken(token).getExpiration();



//        Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(LOGIN_TOKEN_KEY+token);
        String userId = (String) stringRedisTemplate.opsForHash().get(LOGIN_TOKEN_KEY, token);
        log.info("userid;{}",userId);

        if (userId==null||userId.isEmpty()) {
            return unAuthorize(exchange);

        }

        // 刷新TTL
        stringRedisTemplate.expire(LOGIN_TOKEN_KEY + token, 30, TimeUnit.MINUTES);

        //把新的 exchange放回到过滤链
        ServerHttpRequest request = exchange.getRequest().mutate().header(GATEWAY_TOKEN, token).build();
        ServerWebExchange newExchange = exchange.mutate().request(request).build();

//        UserContext.setUser(Long.valueOf(userId));
//        log.info("UserContext.getUser():{}",UserContext.getUser());
        log.info("我放了");
        return chain.filter(newExchange);

    }



    // 返回未登录的自定义错误
    private Mono<Void> unAuthorize(ServerWebExchange exchange) {
        // 设置错误状态码为401
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 设置返回的信息为JSON类型
        exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
        // 自定义错误信息
        String errorMsg = "{\"code\": \"" + 401 + "\"}";
        // 将自定义错误响应写入响应体
        return exchange.getResponse()
                .writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(errorMsg.getBytes())));
    }
}